package tc.jv.task8;

import java.util.Locale;

import tc.jv.task4.AbstractVector;
import tc.jv.task9.IncompatibleVectorSizeException;

public class JVectorAdapter extends AbstractVector
{
	
	/**
	 * 
	 */
	private static final long serialVersionUID = -3661233695545716578L;
	
	private java.util.Vector<Double> vector;
	
	// CONSTRUCTORS
	
	public JVectorAdapter()
	{
		vector = new java.util.Vector<Double>();
	}
	
	public JVectorAdapter(java.util.Vector<Double> vector)
	{
		this.vector = vector; 
	}
	
	// ACCESSORS

	@Override
	public int size()
	{
		return vector.size();
	}

	@Override
	public double get(int index)
	{
		return vector.get(index);
	}

	@Override
	public double set(int index, double value)
	{
		return vector.set(index, value);
	}

	// SUPERCLASS METHODS
	
	@SuppressWarnings("unchecked")
	@Override
	public Object clone()
	{
		JVectorAdapter jva = null;
		
		jva = (JVectorAdapter) super.clone();
		jva.vector = (java.util.Vector<Double>) this.vector.clone();
		
		return jva;
	}
	
	@Override
	public boolean equals(Object obj)
	{
		if (obj == this)
			return true;
		
		if (obj instanceof JVectorAdapter)
		{
			JVectorAdapter jva = (JVectorAdapter) obj;
			return this.size() == jva.size()
				   ? this.vector.equals(jva.vector)
				   : false;
		}
		else if (obj instanceof tc.jv.task4.Vector)
		{
			tc.jv.task4.Vector v = (tc.jv.task4.Vector) obj;
			if (this.size() == v.size())
			{
				boolean e = true;
			
				for (int i = 0; e == true && i < size(); i++)
					e &= (vector.get(i) == v.get(i));
			
				return e;
			}
			else
				return false;
		}
		else
			return false;
	}
	
	@Override
	public int hashCode()
	{
		long lhc = 0;
		
		for (double d : vector)
			lhc ^= (long) d;
		
		int hc = (int) (lhc >> 32) ^ (int) lhc;
		
		return hc;		
	}
	
	@Override
	public String toString()
	{
		String format = "%f\t";				
		return formAString(format);
	}

	// METHODS
	
	@Override
	public String toString(int pcs)
	{
		String format = String.format("%%.%df\t", pcs); // %.<precision>f
		return formAString(format);
	}

	protected String formAString(String format)
	{
		String s = "";
		for (Double d : vector)
			s = s + String.format(Locale.US, format, d);
		return s;
	}

	@Override
	public void print()
	{		
		System.out.println(toString());
	}

	@Override
	public void print(int pcs)
	{		
		System.out.println(toString(pcs));
	}
	
	@Override
	public void addFirst(double value)
	{
		vector.add(0, value);
	}

	@Override
	public void addLast(double value)
	{
		vector.add(value);
	}

	@Override
	public void add(double value)
	{
		vector.add(value);
	}

	@Override
	public boolean add(int index, double value)
	{
		vector.add(index, value);
		return true;
	}

	@Override
	public double remove(int index)
	{
		return vector.remove(index);
	}

	@Override
	public boolean fill(double[] array) throws IncompatibleVectorSizeException
	{
		return fill(array, 0);
	}

	@Override
	public boolean fill(double[] array, int position) throws IncompatibleVectorSizeException
	{
		vectorArgumentCheck(array, position);
		
		for (int i = 0; i < array.length; i++)
			vector.set(position+i, array[i]);
		
		return true;
	}

	@Override
	public boolean fill(tc.jv.task4.Vector v) throws IncompatibleVectorSizeException
	{
		return fill(v, 0);
	}

	@Override
	public boolean fill(tc.jv.task4.Vector v, int position) throws IncompatibleVectorSizeException
	{
		vectorArgumentCheck(v, position);
		
		if (v instanceof JVectorAdapter)
		{
			JVectorAdapter jva = (JVectorAdapter) v;
			vector.addAll(position, jva.vector);
		}
		else
			for (int i = 0; i < v.size(); i++)
				vector.set(position+i, v.get(i));
		
		return true;
	}

	@Override
	public boolean sum(tc.jv.task4.Vector v) throws IncompatibleVectorSizeException
	{
		return sum(v, 0);
	}

	@Override
	public boolean sum(tc.jv.task4.Vector v, int position) throws IncompatibleVectorSizeException
	{
		vectorArgumentCheck(v, position);
		
		for (int i = 0; i < v.size(); i++)
			vector.set(position+i, vector.get(position+i)+v.get(i));
		
		return true;
	}

	@Override
	public boolean multiply(double multiplicator)
	{
		multiplicatorCheck(multiplicator);
		
		for (int i = 0; i < size(); i++)
			vector.set(i, vector.get(i)*multiplicator);
		
		return true;
	}

}
